﻿using System;
using System.Diagnostics;
using System.IO.MemoryMappedFiles;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
using System.Windows.Forms;
using static ShareMemoryDemo.SharedMemoryHelper;

namespace ShareMemoryDemo
{
    public partial class MainForm : Form
    {

        /// <summary>
        /// 内存大小，默认值为100KB。
        /// </summary>
        public int mem_size = 100 * 1024;

        // The enum flag for DwmSetWindowAttribute's second parameter, which tells the function what attribute to set.
        // Copied from dwmapi.h
        public enum DWMWINDOWATTRIBUTE
        {
            DWMWA_WINDOW_CORNER_PREFERENCE = 33
        }

        // The DWM_WINDOW_CORNER_PREFERENCE enum for DwmSetWindowAttribute's third parameter, which tells the function
        // what value of the enum to set.
        // Copied from dwmapi.h
        public enum DWM_WINDOW_CORNER_PREFERENCE
        {
            DWMWCP_DEFAULT = 0,
            DWMWCP_DONOTROUND = 1,
            DWMWCP_ROUND = 2,
            DWMWCP_ROUNDSMALL = 3
        }

        // Import dwmapi.dll and define DwmSetWindowAttribute in C# corresponding to the native function.
        [DllImport("dwmapi.dll", CharSet = CharSet.Unicode, PreserveSig = false)]
        internal static extern void DwmSetWindowAttribute(IntPtr hwnd,
                                                         DWMWINDOWATTRIBUTE attribute,
                                                         ref DWM_WINDOW_CORNER_PREFERENCE pvAttribute,
                                                         uint cbAttribute);

        public MainForm()
        {
            InitializeComponent();
            var attribute = DWMWINDOWATTRIBUTE.DWMWA_WINDOW_CORNER_PREFERENCE;
            var preference = DWM_WINDOW_CORNER_PREFERENCE.DWMWCP_ROUND;
            DwmSetWindowAttribute(this.Handle, attribute, ref preference, sizeof(uint));
        }

        private void MainForm_Load(object sender, EventArgs e)
        {
            string FullName = Assembly.GetExecutingAssembly().FullName;
            string versionName = Assembly.GetExecutingAssembly().GetName().Version.ToString();
            string fileVersionName = FileVersionInfo.GetVersionInfo(Assembly.GetEntryAssembly().Location).ProductVersion;
            // 原文链接：https://blog.csdn.net/sme000/article/details/132394584
            Text += $" Ver.{versionName}";
        }


        private void btnWrite_Click(object sender, EventArgs e)
        {
            WriteMemory(txtWriteName.Text, txtWriteContent.Text, mem_size);
        }

        private void btnRead_Click(object sender, EventArgs e)
        {
            txtReadContent.Text = ReadMemory(txtReadName.Text, mem_size);
        }

        private void MainForm_FormClosing(object sender, FormClosingEventArgs e)
        {

        }

        private void btnClearWriteContent_Click(object sender, EventArgs e)
        {
            txtWriteContent.Text = "";
        }

        private void btnClearReadContent_Click(object sender, EventArgs e)
        {
            txtReadContent.Text = "";
        }

        private void btnClearWriteMemory_Click(object sender, EventArgs e)
        {
            if (txtWriteName.TextLength > 0)
            {
                MemoryMappedFile mmfWrite = MemoryMappedFile.CreateOrOpen(txtWriteName.Text, mem_size);
                // 获取访问器以写入数据
                using (var accessor = mmfWrite.CreateViewAccessor())
                {
                    // 写入数据到共享内存
                    string s = "\0";
                    byte[] bytes = Encoding.UTF8.GetBytes(s);
                    byte[] vs = new byte[mem_size];
                    for (int i = 0; i < bytes.Length; i++)
                    {
                        vs[i] = (byte)bytes[i];
                        accessor.Write<byte>(i, ref vs[i]);
                    }
                }
            }
        }

        private void btnClearReadMemory_Click(object sender, EventArgs e)
        {
            if (txtReadName.TextLength > 0)
            {
                MemoryMappedFile mmfWrite = MemoryMappedFile.CreateOrOpen(txtReadName.Text, mem_size);
                // 获取访问器以写入数据
                using (var accessor = mmfWrite.CreateViewAccessor())
                {
                    // 写入数据到共享内存
                    string s = "\0";
                    byte[] bytes = Encoding.UTF8.GetBytes(s);
                    byte[] vs = new byte[mem_size];
                    for (int i = 0; i < bytes.Length; i++)
                    {
                        vs[i] = (byte)bytes[i];
                        accessor.Write<byte>(i, ref vs[i]);
                    }
                }
            }
        }

        private void ckAutoRead_CheckedChanged(object sender, EventArgs e)
        {
            timer1.Enabled = ckAutoRead.Checked;
            btnRead.Enabled = !ckAutoRead.Checked;
            btnClearReadContent.Enabled = !ckAutoRead.Checked;
        }

        private void timer1_Tick(object sender, EventArgs e)
        {
            var str = ReadMemory(txtReadName.Text);
            if (!string.IsNullOrEmpty(str) && str.Trim().Length > 0)
            {
                txtReadContent.Text = str;
                WriteMemory(txtReadName.Text, "");
            }
        }
    }
}
